package sanrenxing.Paper.servlet;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import sanrenxing.Paper.dao.SubjectDao;
import sanrenxing.Paper.dao.impl.SubjectDaoImpl;
import sanrenxing.Paper.dao.impl.PaperDaoImpl;
import sanrenxing.Paper.domain.*;
import sanrenxing.Paper.dao.PaperDao;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 功能：制作试卷功能
 * 编写者：张港峰
 * 日期：20201010
 * 版本：1.0
 */
@WebServlet("/PaperServlet")
public class PaperServlet extends HttpServlet {
    //定义数据层对象
    private PaperDao paperDao=new PaperDaoImpl();
    private SubjectDao subjectDao =new SubjectDaoImpl();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");

        //获取请求路径中的操作方式
        String method=req.getParameter("method");
        //判断操作方式 执行方法代码
        if("findAll".equals(method)){
            //调用查询所有的方法
            findAll(req,resp);
        } else if("edit".equals(method)){
            //调用修改的方法
            edit(req,resp);
        }else if("delete".equals(method)){
            //删除单行的方法
            delete(req,resp);
        }else if("allDelete".equals(method)){
            //删除多行的方法
            allDelete(req,resp);
        }else if("add".equals(method)){
            System.out.println("Pa");
            add(req,resp);
        }else if("gjadd".equals(method)){
            gjadd(req,resp);
        }else if ("findSubject".equals(method)){
            findSubject(req,resp);
        }

    }

    /**
     * 查询题目
     * @param req
     * @param resp
     */
    private void findSubject(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        PrintWriter out=resp.getWriter();
        //获取题目编号
        String subjectIds=req.getParameter("subjectIds");
        //创建保存题目的数组
        List<Subjects> subjectsList=new ArrayList<>();
        //定义一个字符串数组用于接收题目编号
        String[] str=subjectIds.split(",");
        for (String subjectId:str) {
            //调用数据层代码用于查询题目,返回题目对象保存到数组当中
            subjectsList.add(paperDao.findSubjectIds(subjectId));
        }
        Gson gson=new Gson();
        String json=gson.toJson(subjectsList);
        out.print(json);
    }

    /**
     * 高级组卷
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    private void gjadd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建输出流对象
        PrintWriter out=resp.getWriter();
        //获取单选题数量
        int odd=Integer.parseInt(req.getParameter("odd"));
        //获取多选题数量
        int more=Integer.parseInt(req.getParameter("more"));
        //获取课程名称
        String courseName=req.getParameter("courseId");
        int courseId=paperDao.findCourseId(courseName);
        //获取班级名称
        String className=req.getParameter("classId");
        int classId=paperDao.findClassId(className);
        //获取考试日期
        String examDate=req.getParameter("examDate");
        //获取开始时间
        String beginTime=req.getParameter("beginTime");
        //获取结束时间
        String finishTime=req.getParameter("finishTime");
        //获取单选简单题量
        int odd1=Integer.parseInt(req.getParameter("odd1"));
        //获取单选中等题量
        int odd2=Integer.parseInt(req.getParameter("odd2"));
        //获取单选困难题量
        int odd3=Integer.parseInt(req.getParameter("odd3"));
        //获取多选简单题量
        int more1=Integer.parseInt(req.getParameter("more1"));
        //获取多选中等题量
        int more2=Integer.parseInt(req.getParameter("more2"));
        //获取多选困难题量
        int more3=Integer.parseInt(req.getParameter("more3"));

        //定义简单试题组
        ArrayList<Subject> simpleness=new ArrayList<>();
        //定义中等试题组
        ArrayList<Subject> common=new ArrayList<>();
        //定义困难试题组
        ArrayList<Subject> harder=new ArrayList<>();

        //定义简单试题组
        ArrayList<Subject> Simpleness=new ArrayList<>();
        //定义中等试题组
        ArrayList<Subject> Common=new ArrayList<>();
        //定义困难试题组
        ArrayList<Subject> Harder=new ArrayList<>();

        //创建随机类
        Random ran=new Random();
        for (int i=1;i<5;i++){
            ArrayList<Subject> jd = subjectDao.getSubjectss(courseId,i,"单选");
            //添加到简单试题中
            simpleness.addAll(jd);
        }

        for (int i=5;i<9;i++){
            ArrayList<Subject> zd = subjectDao.getSubjectss(courseId,i,"单选");
            //添加到中等试题中
            common.addAll(zd);
        }

        for (int i=9;i<11;i++){
            ArrayList<Subject> gd = subjectDao.getSubjectss(courseId,i,"单选");
            //添加到困难试题中
            harder.addAll(gd);
        }


        for (int i=1;i<5;i++){
            ArrayList<Subject> jd = subjectDao.getSubjectss(courseId,i,"多选");
            //添加到简单试题中
            Simpleness.addAll(jd);
        }

        for (int i=5;i<9;i++){
            ArrayList<Subject> zd = subjectDao.getSubjectss(courseId,i,"多选");
            //添加到中等试题中
            Common.addAll(zd);
        }

        for (int i=9;i<11;i++){
            ArrayList<Subject> gd = subjectDao.getSubjectss(courseId,i,"多选");
            //添加到困难试题中
            Harder.addAll(gd);
        }

        //定义单选试题组的数组集合
        ArrayList<Subject> subject1 = subjectDao.getSubjects(courseId,"单选");
        //定义多选试题组的数组集合
        ArrayList<Subject> subject2 = subjectDao.getSubjects(courseId,"多选");

        //hashset定义困难试题集合
        HashSet<String> harderList=new HashSet<>();
        //定义中等试题集合
        HashSet<String> commonList=new HashSet<>();
        //定义简单试题集合
        HashSet<String> simplenessList=new HashSet<>();

        //定义困难试题集合
        HashSet<String> HarderList=new HashSet<>();
        //定义中等试题集合
        HashSet<String> CommonList=new HashSet<>();
        //定义简单试题集合
        HashSet<String> SimplenessList=new HashSet<>();


        ArrayList<String> aaa=new ArrayList<>();


        //判断单选题不等于简单单选题加中等单选题加困难单选题或多选题...
        if (odd!=odd1+odd2+odd3 || more!=more1+more2+more3 ){
            out.print("<script type='text/javascript'>alert('难度试题数应与类型试题数对等')</script>");
            return ;
        }

        //判断单选加多选不等于50或各类型试题数相加不等于50
        if (odd+more!=50 || odd1+odd2+odd3+more1+more2+more3!=50){
            out.print("<script type='text/javascript'>alert('试题数量不足')</script>");
            return ;
        }

        //判断单选试题组和多选试题组长度的和大于等于单选试题数加多选是试题数
        if (subject1.size()+ subject2.size()>=odd+more){
            //单选试题组长度大于等于单选试题
            if (subject1.size()>=odd){
                //循环判断harderList的长度小于困难单选题数
                while (harderList.size()<odd3){
                    //判断困难题的长度大于0
                    if (harder.size()>0){
                        //定义随机困难单选题的长度
                        int dan3=ran.nextInt(harder.size());
                        //添加到harderList中
                        harderList.add(harder.get(dan3).getSubjectId()+",");
                    }
                    //判断harderList的长度大于等于困难试题的长度
                    if (harderList.size()>=harder.size()){
                        //定义随机中等单选题的长度
                        int dan2=ran.nextInt(common.size());
                        //添加到harderList中
                        harderList.add(common.get(dan2).getSubjectId()+",");
                        //判断harderList的长度大于等于困难试题的长度加中等试题的长度
                        if (harderList.size()>=harder.size()+common.size()){
                            //定义随机简单单选题的长度
                            int dan1=ran.nextInt(simpleness.size());
                            //添加到harderList中
                            harderList.add(simpleness.get(dan1).getSubjectId()+",");
                        }
                    }
                }

                aaa=new ArrayList<>(harderList);

                //循环判断harderList的长度小于中等多选题加aaa的长度
                while (harderList.size()<odd2+aaa.size()){
                    //如果中等试题的长度大于0
                    if (common.size()>0){
                        //定义随机中等单选题的长度
                        int dan2=ran.nextInt(common.size());
                        //添加到harderList中
                        harderList.add(common.get(dan2).getSubjectId()+",");
                    }
                    //如果harderList的长度大于等于中等试题的长度加aaa的长度
                    if (harderList.size()>=common.size()+aaa.size()){
                        //定义随机简单单选题的长度
                        int dan1=ran.nextInt(simpleness.size());
                        //添加到harderList中
                        harderList.add(simpleness.get(dan1).getSubjectId()+",");
                    }
                }
                aaa=new ArrayList<>(harderList);

                //循环判断harderList的长度小于简单单选题加aaa的长度
                while (harderList.size()<odd1+aaa.size()){
                    //判断简单试题的长度大于0
                    if (simpleness.size()>0){
                        //定义随机简单单选题的长度
                        int dan1=ran.nextInt(simpleness.size());
                        //添加到harderList中
                        harderList.add(simpleness.get(dan1).getSubjectId()+",");
                    }
                    //判断harderList的长度大于等于简单试题的长度加aaa的长度
                    if (harderList.size()>=simpleness.size()+aaa.size()){
                        //定义随机简单单选题的长度
                        int dan1=ran.nextInt(common.size());
                        //添加到harderList中
                        harderList.add(common.get(dan1).getSubjectId()+",");
                        //判断简单试题的长度加中等试题的长度加aaa的长度小于等于harderList的长度
                        if (simpleness.size()+common.size()+aaa.size()<=harderList.size()){
                            //定义随机困难单选题的长度
                            int dan3=ran.nextInt(harder.size());
                            //添加到harderList中
                            harderList.add(harder.get(dan3).getSubjectId()+",");
                        }
                    }
                }
                aaa=new ArrayList<>(harderList);
            }else {
                //循环获取单选试题组的长度
                for (int i = 1; i<= subject1.size(); i++){
                    //定义随机单选试题组的长度
                    int dan=ran.nextInt(subject1.size());
                    //添加到harderList中
                    harderList.add(subject1.get(dan).getSubjectId()+",");
                }
                //循环获取多选试题组的长度
                for (int i = 1; i<=odd- subject1.size(); i++){
                    //定义随机多选试题组的长度
                    int duo=ran.nextInt(subject2.size());
                    //添加到harderList中
                    harderList.add(subject2.get(duo).getSubjectId()+",");
                }
                aaa=new ArrayList<>(harderList);
            }

            //判断多选试题组的长度大于等于多选题
            if (subject2.size()>=more){
                //循环判断harderList的长度小于困难多选题加aaa的长度
                while (harderList.size()<more3+aaa.size()){
                    //判断困难题的长度大于0
                    if (Harder.size()>0){
                        //定义随机困难多选题的长度
                        int duo3=ran.nextInt(Harder.size());
                        //添加到harderList中
                        harderList.add(Harder.get(duo3).getSubjectId()+",");
                    }
                    //判断harderList的长度大于等于困难试题的长度加aaa的长度
                    if (harderList.size()>=Harder.size()+aaa.size()){
                        //定义随机中等多选题的长度
                        int duo2=ran.nextInt(Common.size());
                        //添加到harderList中
                        harderList.add(Common.get(duo2).getSubjectId()+",");
                        //判断harderList的长度大于等于困难试题的长度加中等试题的长度加aaa的长度
                        if (harderList.size()>=Harder.size()+Common.size()+aaa.size()){
                            //定义随机简单多选题的长度
                            int duo1=ran.nextInt(Simpleness.size());
                            //添加到harderList中
                            harderList.add(Simpleness.get(duo1).getSubjectId()+",");
                            //判断harderList的长度大于等于困难试题的长度加中等试题的长度加简单试题的长度加aaa的长度
                            if (harderList.size()>=Harder.size()+Common.size()+Simpleness.size()+aaa.size()){
                                //定义单选试题组的长度
                                int dan=ran.nextInt(subject1.size());
                                //添加到harderList中
                                harderList.add(subject1.get(dan).getSubjectId()+",");
                            }
                        }
                    }
                }
                aaa=new ArrayList<>(harderList);

                //循环判断harderList的长度小于中等多选试题加aaa的长度
                while (harderList.size()<more2+aaa.size()){
                    //判断中等试题的长度大于0
                    if (Common.size()>0){
                        //定义中等多选试题的长度
                        int duo2=ran.nextInt(Common.size());
                        //添加到harderList中
                        harderList.add(Common.get(duo2).getSubjectId()+",");
                    }
                    //判断harderList的长度大于等于中等试题的长度加aaa的长度
                    if (harderList.size()>=Common.size()+aaa.size()){
                        //定义简单多选试题的长度
                        int duo1=ran.nextInt(Simpleness.size());
                        //添加到harderList中
                        harderList.add(Simpleness.get(duo1).getSubjectId()+",");
                        //判断harderList的长度大于等于中等试题的长度加简单试题的长度加aaa的长度
                        if (harderList.size()>=Common.size()+Simpleness.size()+aaa.size()){
                            //定义随机单选试题组的长度
                            int dan=ran.nextInt(subject1.size());
                            //添加到harderList中
                            harderList.add(subject1.get(dan).getSubjectId()+",");
                        }
                    }
                }
                aaa=new ArrayList<>(harderList);

                //循环判断harderList的长度小于简单多选题加aaa的长度
                while (harderList.size()<more1+aaa.size()){
                    //判断简单试题的长度大于0
                    if (Simpleness.size()>0){
                        //定义随机简单多选试题的长度
                        int duo1=ran.nextInt(Simpleness.size());
                        //添加到harderList中
                        harderList.add(Simpleness.get(duo1).getSubjectId()+",");
                    }
                    //判断harderList的长度大于等于简单试题的长度加aaa的长度
                    if (harderList.size()>=simpleness.size()+aaa.size()){
                        //定义随机中等多选试题的长度
                        int duo2=ran.nextInt(common.size());
                        //添加到harderList中
                        harderList.add(common.get(duo2).getSubjectId()+",");
                        //判断harderList的长度大于等于中等试题的长度加简单试题的长度加aaa的长度
                        if (harderList.size()>=common.size()+simpleness.size()+aaa.size()){
                            //判断困难试题的长度大于0
                            if (harder.size()>0){
                                //定义随机困难多选试题的长度
                                int duo3=ran.nextInt(Harder.size());
                                //添加到harderList中
                                harderList.add(Harder.get(duo3).getSubjectId()+",");
                            }
                            //判断harderList的长度大于等于中等试题的长度加简单试题的长度加困难试题的长度加aaa的长度
                            if (harderList.size()>=Common.size()+Simpleness.size()+Harder.size()+aaa.size()){
                                //定义随机单选试题组的长度
                                int dan=ran.nextInt(subject1.size());
                                //添加到harderList中
                                harderList.add(subject1.get(dan).getSubjectId()+",");
                            }
                        }
                    }
                }
            }else {
                //循环判断harderList的长度小于多选试题组的长度加aaa的长度
                while (harderList.size()< subject2.size()+aaa.size()){
                    //定义随机多选试题组的长度
                    int duo=ran.nextInt(subject2.size());
                    //添加到harderList中
                    harderList.add(subject2.get(duo).getSubjectId()+",");
                }
                aaa=new ArrayList<>(harderList);

                //循环判断harderList的长度小于多选题-多选试题组的长度加aaa的长度
                while (harderList.size()<more- subject2.size()+aaa.size()){
                    //定义随机单选试题组的长度
                    int dan=ran.nextInt(subject1.size());
                    //添加到harderList中
                    harderList.add(subject1.get(dan).getSubjectId()+",");
                }
            }
        }else{
            out.print("<script type='text/javascript'>alert('试题数量不足，请添加试题或选择其他课程')</script>");
            return;
        }

        //定义试题编号组为空
        String subjectIds="";
        for(String h:harderList){
            subjectIds+=h;

        }
        //添加到试卷对象中
        Paper paper=new Paper(classId,courseId,subjectIds,examDate,beginTime,finishTime);

        //调用数据层的添加方法
        PaperDao paperDao=new PaperDaoImpl();
        int rows=paperDao.add(paper);
        //调用数据层学员集合得到班级编号
        ArrayList<Student> students= (ArrayList<Student>) paperDao.QueryAllStudent(classId);


        Gson gson=new Gson();
        //创建session
        HttpSession session=req.getSession();
        //通过session传数据
        session.setAttribute("json",students);
        //将集合转换为json
        String json=gson.toJson(students);
        System.out.println(json);
        //发送数据
        out.print(json);

        if (rows>0){
            //调用方法，增加学员考试状态
            this.addStatu(students,classId,req);
            //跳转页面
            resp.sendRedirect("jsp/BackPaper.jsp");

        }else {
            out.print("添加失败");
        }

    }

    /**
     * 查询所有
     * @param req 请求对象
     * @param resp 响应对象
     * @throws ServletException Servlet异常
     * @throws IOException IO异常
     */
    private void findAll(HttpServletRequest req, HttpServletResponse resp)  throws ServletException, IOException {
        //创建输出流对象
        PrintWriter out=resp.getWriter();
        //获取当前页数
        String pageStr = req.getParameter("page");
        //定义页数为1
        int page = 1;
        if(pageStr!=null && pageStr.trim().length()!=0){
            //转换类型为int
            page = Integer.parseInt(pageStr);
        }
        //获取每页行数
        String rowsStr = req.getParameter("limit");
        //定义行数为5
        int rows = 5;
        if(rowsStr!=null && rowsStr.trim().length()!=0){
            //转换类型为int
            rows = Integer.parseInt(rowsStr);
        }
        //定义用于构造多条件查询的试卷对象
        Paper paper=new Paper();

        //获取来自请求中的班级编号
        String className=req.getParameter("className");
        //判断班级编号，是否加入到试卷对象中
        if(className!=null && className.trim().length()!=0){
            //根据班级编号查询班级名称
            int classId=paperDao.findClassId(className);
            //添加到试卷对象中
            paper.setClassId(classId);
        }

        //获取来自请求中的课程编号
        String courseName=req.getParameter("courseName");
        //判断课程编号是否加入到试卷对象中
        if(courseName!=null && courseName.trim().length()!=0){
            //根据课程编号查询课程名称
            int courseId=paperDao.findCourseId(courseName);
            //添加到试卷对象中
            paper.setCourseId(courseId);
        }

        //获取来自请求中的考试日期
        String examDate=req.getParameter("examDate");
        //判断考试日期是否加入到试卷对象中
        if(examDate!=null && examDate.trim().length()!=0){
            //添加到试卷对象中
            paper.setExamDate(examDate);
        }

        //调用数据方法，根据试卷对象构造查询条件字符串
        String condition=paperDao.getCondition(paper);
        //执行多条件分页查询
        List<PaperTo> paperToList=paperDao.findByPage(rows,page,condition);
        //多条件查询表中总记录数
        int totalRows=paperDao.count(condition);


        //定义映射集合对象
        Map<String,Object> mapData=new HashMap<String,Object>();
        //在映射集合中添加key为code，值为0的状态码
        mapData.put("code",0);
        //在映射集合中添加key为msg,值为响应信息字符串
        mapData.put("msg","");
        //在映射集合中添加key为count,值总行数的数据对
        mapData.put("count",totalRows);
        //在映射集合中添加key为data,值为集合对象
        mapData.put("data",paperToList);
        //建立Gson对象
        Gson gson=new Gson();
        //使用Gson对象把映射集合转换为json格式数据
        String json1=gson.toJson(mapData);
        //将json数据输出到客户端
        out.write(json1);
        //关闭输出流对象
        out.close();
    }

    /**
     * 批量删除数据
     * @param req 请求对象
     * @param resp 响应对象
     * @throws ServletException Servlet异常
     * @throws IOException IO异常
     */
    private void allDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
        //定义输出流对象
        PrintWriter out=resp.getWriter();
        //得到来自请求中的试卷编号
        String paperIdStr=req.getParameter("paperIdStr");
        //对试卷编号字符串按","进行分割
        String[] paperIds=paperIdStr.split(",");
        //使用异常和循环来进行判断删除是否成功
        try{
            //循环删除
            for(String paperStr:paperIds){
                //把字符串转换为整型的试卷编号
                int paperId=Integer.parseInt(paperStr);
                //调用数据层代码进行删除
                paperDao.delete(paperId);
            }
            //向客户端发送操作结果
            out.print("ok");
        }catch(Exception e){
            out.print("no");
        }
        //关闭输出流对象
        out.close();


    }

    /**
     * 删除单行数据
     * @param req 请求对象
     * @param resp 响应对象
     * @throws ServletException Servlet异常
     * @throws IOException IO异常
     */
    private void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
        //定义输出流对象
        PrintWriter out=resp.getWriter();
        //得到来自请求中的试卷编号
        String paperIdStr=req.getParameter("paperId");
        try{
            //把字符串转换为整型的试卷编号
            int paperId=Integer.parseInt(paperIdStr);
            //调用数据层代码进行删除
            paperDao.delete(paperId);
            //向客户端发送操作结果
            out.print("ok");
        }catch(Exception e){
            out.print("no");
        }
        //关闭输出流对象
        out.close();
    }

    /**
     * 修改数据
     * @param req 请求对象
     * @param resp 响应对象
     * @throws ServletException Servlet异常
     * @throws IOException IO异常
     */
    private void edit(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //定义输出对象
        PrintWriter out=resp.getWriter();
        //接收来自前端请求的json数据字符串
        String json=req.getParameter("json");
        //接收试卷编号
        int paperId= Integer.parseInt(req.getParameter("paperId"));
        //接收班级编号
        String className=req.getParameter("className");
        //接收课程名称
        String courseName=req.getParameter("courseName");
        //调用数据层方法查询班级编号
        int classId=paperDao.findClassId(className);
        //调用数据层方法查询课程名称
        int courseId=paperDao.findCourseId(courseName);
        //定义Gson操作对象
        Gson gson = new Gson();
        //通过gson对象将json数据转换成试卷对象
        Paper paper= null;
        try {
            paper=gson.fromJson(json,Paper.class);
            //修改对象中的classId
            paper.setClassId(classId);
            //修改对象中得courseId
            paper.setCourseId(courseId);
        }catch (JsonSyntaxException e){
            e.printStackTrace();
        }
        //调用数据层方法，实现修改
        int rows=paperDao.update(paper);
        //判断是否有对应试卷的考试状态，如果有，则删除并添加新的考试状态
        //调用数据层方法删除考生状态的信息
        paperDao.deleteStatu(paperId);
        //通过班级编号查询出对应班级所有学员的对象
        List<Student> studentList=paperDao.QueryAllStudent(paper.getClassId());
        //定义变量保存公告内容
        String noticeBody=className+"班于"+paper.getExamDate()+"号考试，考试具体时间为:"+paper.getBeginTime()+"-"+paper.getFinishTime();
        //获得当前日期
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        String newDate=sdf.format(new Date());
        //创建session对象
        HttpSession session=req.getSession();
        //创建公告对象
        AddNotice addNotice=new AddNotice((Integer) session.getAttribute("teacherId"),noticeBody,classId,newDate,paper.getExamDate());
        //调用数据层方法添加公告
        paperDao.addNoticeMsg(addNotice);
        //添加对应班级所有学员的考试状态信息和添加公告
        for (Student s:studentList) {
            paperDao.addStuStatu(paperId,s,classId);
        }
        //判断操作是否成功
        if(rows>0){
            //成功
            out.print("ok");
        }else{
            //失败
            out.print("no");
        }
        //关闭输出流对象
        out.close();
    }

    /**
     * 自动组卷
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    private void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建输出对象
        PrintWriter out=resp.getWriter();
        //获取单选试题数
        int odd=Integer.parseInt(req.getParameter("odd"));
        //获取多选试题数
        int more=Integer.parseInt(req.getParameter("more"));
        //获取课程名称
        String courseName=req.getParameter("courseId");
        int courseId=paperDao.findCourseId(courseName);
        //获取班级名称
        String className=req.getParameter("classId");
        int classId=paperDao.findClassId(className);
        //获取考试日期
        String examDate=req.getParameter("examDate");
        //获取开始时间
        String beginTime=req.getParameter("beginTime");
        //获取结束时间
        String finishTime=req.getParameter("finishTime");
        //创建hashset集合 唯一性
        HashSet<String> Title1=new HashSet<>();
        HashSet<String> Title2=new HashSet<>();
        //创建随机类
        Random ran=new Random();
        //System.out.println(odd+more);
        //定义单选试题组的数组集合
        ArrayList<Subject> subject1 = subjectDao.getSubjects(courseId,"单选");
        //定义多选试题组的数组集合
        ArrayList<Subject> subject2 = subjectDao.getSubjects(courseId,"多选");

        //循环判断title2的长度小于多选试题
        while(Title2.size()<more){
            //定义一个随机数来保存多选试题组的长度
            int randomNumber = ran.nextInt(subject2.size());
            //添加到title2中
            Title2.add(subject2.get(randomNumber).getSubjectId()+",");
            //判断title2的长度大于等于多选试题组的长度
            if(Title2.size()>= subject2.size()){
                //定义一个i1来保存单选试题组的长度
                int i1=ran.nextInt(subject1.size());
                //添加到title2中
                Title2.add(subject1.get(i1).getSubjectId()+",");
            }
        }

        //循环判断title1的长度小于单选试题
        while (Title1.size()<odd){
            //定义一个随机数来保存单选试题组的长度
            int randomNumbers=ran.nextInt(subject1.size());
            //添加到title1中
            Title1.add(subject1.get(randomNumbers).getSubjectId()+",");
        }

        //定义试题编号组为空
        String subjectIds="";
        for(String s:Title1){
            subjectIds+=s;
        }

        for (String z:Title2){
            subjectIds+=z;
        }

        //把数据封装成对象
        Paper paper = new Paper(classId, courseId, subjectIds, examDate, beginTime, finishTime);

        //调用数据层的添加方法
        PaperDao paperDao = new PaperDaoImpl();
        int rows = paperDao.add(paper);
        //调用数据层学员集合得到班级编号
        ArrayList<Student> students= (ArrayList<Student>) paperDao.QueryAllStudent(classId);

        //定义gson
        Gson gson=new Gson();
        //定义session对象
        HttpSession session=req.getSession();
        //通过session传数据
        session.setAttribute("json",students);
        //将集合转换为json
        String json=gson.toJson(students);
        //System.out.println(json);
        //发送数据
        out.print(json);

        //判断是否添加成功
        if (rows > 0) {
            //调用方法，增加学员考试状态
            this.addStatu(students,classId,req);
            resp.sendRedirect("jsp/BackPaper.jsp");

        } else {
            out.print("添加失败");
        }
    }

    /**
     * 增加学员状态方法
     * @param students
     * @param classId
     */
    private void addStatu(List<Student> students, int classId,HttpServletRequest req) {
        //调用数据层方法查询试卷编号
        int paperId=paperDao.selectStudentStatu();
        //通过编号查询对应试卷信息
        Paper paper=paperDao.findPaperMsg(paperId);
        //调用数据层方法，通过科目编号查询科目名称
        String courseName=paperDao.findcourseName(paper.getCourseId());
        //通过试卷编号查询班级名称
        String className=paperDao.findClassName(paper.getClassId());
        //创建session对象
        HttpSession session=req.getSession();
        //定义变量保存公告内容
        String noticeBody=className+"班于"+paper.getExamDate()+"号参加"+courseName+"考试，考试具体时间为:"+paper.getBeginTime()+"-"+paper.getFinishTime();
        //获得当前日期
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        String newDate=sdf.format(new Date());
        //创建公告对象
        AddNotice addNotice=new AddNotice((Integer) session.getAttribute("teacherId"),noticeBody,classId,newDate,paper.getExamDate());
        //调用数据层方法添加公告
        paperDao.addNoticeMsg(addNotice);
        //调用数据层方法添加学员考试状态
        for (Student s:students) {
            paperDao.addStuStatu(paperId,s,classId);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }


}
